package com.jalarbee.core.user.business;

import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;

import com.jalarbee.core.business.BaseEntity;
import javax.persistence.CollectionTable;
import javax.persistence.ElementCollection;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(length = 60, discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("U")
public class User extends BaseEntity {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;

	private Profile profile;

	private Credentials credentials;

	// @OneToMany(cascade={CascadeType.PERSIST, CascadeType.MERGE})
	// this is the hibernate way of mapping enum collections
	// @Basic
	@ElementCollection(fetch = FetchType.EAGER)
	@CollectionTable(name = "PERMISSION", joinColumns = @JoinColumn(name = "USER_ID"))
	@Column(name = "ROLE", nullable = false)
	@Enumerated(EnumType.STRING)
	private Set<Role> roles;

	@OneToOne(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST,
			CascadeType.REMOVE })
	private RegistrationInfo registrationInfo;

	@OneToOne(fetch = FetchType.LAZY)
	private Contact contact;

	@OneToOne(fetch = FetchType.LAZY, optional = true)
	private IdentificationDocument identificationDocument;

	public int getId() {
		return id;
	}

	@SuppressWarnings("unused")
	private void setId(int id) {
		this.id = id;
	}

	public Set<Role> getRoles() {
		return roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}

	public Credentials getCredentials() {
		return credentials;
	}

	public void setCredentials(Credentials credentials) {
		this.credentials = credentials;
	}

	public Contact getContact() {
		return contact;
	}

	public void setContact(Contact contact) {
		this.contact = contact;
	}

	public Profile getProfile() {
		return profile;
	}

	public void setProfile(Profile profile) {
		this.profile = profile;
	}

	public RegistrationInfo getRegistrationInfo() {
		return registrationInfo;
	}

	public void setRegistrationInfo(RegistrationInfo registrationInfo) {
		this.registrationInfo = registrationInfo;
	}

	public IdentificationDocument getIdentificationDocument() {
		return identificationDocument;
	}

	public void setIdentificationDocument(
			IdentificationDocument identificationDocument) {
		this.identificationDocument = identificationDocument;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof User)) {
			return false;
		}
		User tmp = (User) obj;
		if (id == tmp.getId()) {
			return true;
		}
		return false;
	}

	@Override
	public int hashCode() {
		return (id * 32 + profile.getFirstName().hashCode() + 35) + 7;
	}

	@Override
	public String toString() {
		return profile.getTitle() + profile.getFirstName()
				+ profile.getMiddleName() + profile.getLastName();
	}

}
